package com.sokobanboxpro.game;

import com.sokobanboxpro.game.managers.ActionGameManager;
import com.sokobanboxpro.game.managers.ActionMenuManager;
import com.sokobanboxpro.game.managers.GraphicsManager;
import com.sokobanboxpro.game.system.Config;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.Log;

/**
 * Класс приложение. Основной класс, инициализирующийся первым среди классов
 * описывающих логику приложения
 *
 * @author Esr
 */
public class Application extends BasicGame {

		/**
		 * Название игры
		 */
		public static final String GAME_NAME = "Sokoban Box Pro";
		/**
		 * Версия игры
		 */
		public static final double VERSION = 0.05;
		/**
		 * Текущее состояние игры (В меню или в игре)
		 */
		public static ApplicationState applicationState;
		/**
		 * Ошибка при загрузке
		 */
		private boolean loadError = false;

		/**
		 * Создает приложение, открывает окно
		 */
		public Application() {

				super(GAME_NAME + " ver. " + VERSION);
				try {
						Config.load("/resource/config.cfg", true);
						Log.setLogSystem(new com.sokobanboxpro.game.system.Logger());
				} catch (Exception ex) {
						Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
				}

		}

		/**
		 * Иницилизирует игру
		 *
		 * @param gc
		 * @throws SlickException
		 */
		@Override
		public void init(GameContainer gc) throws SlickException {

				gc.setShowFPS(false);

				try {

						if (Config.toBool("SkipMenu")) {
								applicationState = ApplicationState.GAME;
						} else {
								applicationState = ApplicationState.MENU;
						}

						ActionMenuManager.init();
						ActionGameManager.init();
						GraphicsManager.init();

				} catch (Exception ex) {
						Log.error("При загрузке: " + ex);
						ex.printStackTrace();
						loadError = true;
				}

		}

		/**
		 * Функция обновления логики
		 *
		 * @param gc
		 * @param delta Время прошедшее с момента предыдушего вызова
		 * @throws SlickException
		 */
		@Override
		public void update(GameContainer gc, int delta) throws SlickException {

				if (loadError) {
						throw new SlickException("Ошибка при загрузке");
				}

				try {
						if (applicationState == ApplicationState.MENU) {
								ActionMenuManager.update(gc, delta);
						} else {
								ActionGameManager.update(gc, delta);
						}
				} catch (Exception ex) {
						Log.error("Логика: " + ex.getMessage());
						ex.printStackTrace();
				}

		}

		/**
		 * Функция обновления графики
		 *
		 * @param gc
		 * @param grphcs
		 * @throws SlickException
		 */
		@Override
		public void render(GameContainer gc, Graphics grphcs) throws SlickException {

				if (loadError) {
						throw new SlickException("Ошибка при загрузке");
				}
				try {
						GraphicsManager.render(gc, grphcs);
				} catch (Exception ex) {
						Log.error("Графика: " + ex.getMessage());
						ex.printStackTrace();
				}

		}

		/**
		 * Функция вызываемая при нажатие клавиши мыши
		 *
		 * @param button номер кнопки
		 * @param x координата по горизонтали
		 * @param y координата по вертикали
		 */
		@Override
		public void mousePressed(int button, int x, int y) {

				try {
						if (applicationState == ApplicationState.MENU) {
								ActionMenuManager.mousePressed(x, y);
						} else {
								ActionGameManager.mousePressed(x, y);
						}
				} catch (Exception ex) {
						Log.error("Ошибка нажатия: " + ex.getMessage());
						ex.printStackTrace();
				}

		}

		/**
		 * Функция перемешения мыши
		 *
		 * @param oldx старая координата по горизонтали
		 * @param oldy старая координата по вертикали
		 * @param newx новая координата по горизонтали
		 * @param newy новая координата по вертикали
		 */
		@Override
		public void mouseDragged(int oldx, int oldy, int newx, int newy) {
		}

}
